# 定义函数
def greet_user():
    """显示简单的问候语"""
    print("hello!")

greet_user()


#向函数传参
def greet_user(username):
    """show simple hello"""
    print(f"hello, {username.title()}!")

greet_user("zhangsan")

# 传递实参
## 位置实参
def describe_pet(animal_type,pet_name):
    """show pet's information"""
    print(f"\nI have a {animal_type}")
    print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet("hamster","harry")
### 调用多次
describe_pet("dog","white")

## 关键字实参
def describe_pet(animal_type,pet_name):
    """show pet's information"""
    print(f"\nI have a {animal_type}")
    print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet(animal_type="hamster2",pet_name="harry2")
describe_pet(pet_name="harry3",animal_type="hamster3")

## 默认值
def describe_pet(pet_name,animal_type = "dog"):  ## 有默认参数必须放到最后
    """show pet's information"""
    print(f"\nI have a {animal_type}")
    print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet(pet_name="harry4")
describe_pet("harry5")

# 返回值
def get_formatted_name(first_name,last_name):
    """return formatted name"""
    full_name = f"{first_name} {last_name}"
    full_name2 = first_name + " " + last_name
    return full_name2.title()
musician = get_formatted_name("jimi","hendrix")
print(musician)

##让实参变成可选的
def get_formatted_name(first_name,last_name,middle_name=""):
    """return formatted name"""
    if middle_name:
        full_name = f"{first_name} {middle_name} {last_name}"
    else:
        full_name = f"{first_name} {last_name}"
    return full_name.title()
musician = get_formatted_name("jimi","hendrix","lee")
print(musician)
musician = get_formatted_name("jimi","hendrix")
print(musician)

## 返回字典
def build_person(first_name,last_name,age=None): #None用于占位，条件测试可以看为 False
    """返回字典 包含一个人的信息"""
    person = {"first_name":first_name,"last_name":last_name}
    if age:
        person["age"] = age
        print(type(age))
    return person
musician = build_person("jimi","hendrix")
print(musician)
musician = build_person("jimi","hendrix",22)
print(musician)

## 结合使用函数和 while 循环

def get_formatted_name(first_name,last_name):
    """return formatted name"""
    full_name = f"{first_name} {last_name}"
    return full_name.title()
while True:
    print("\n Please tell me you name:")
    print("enter 'q' at any time to quit")
    f_name = input("First name:")
    if f_name == "q":
        break
    l_name = input("Last name:")
    if l_name == "q":
        break
    formatted_name = get_formatted_name(f_name,l_name)
    print(formatted_name)

# 传递列表
def greet_users(names):
    """say hello to everyone who in array_list"""
    for name in names:
        msg = f"Hello,{name.title()}"
        print(msg)
usernames = ["hannah","ty","margot"]
greet_users(usernames)

## 例子：函数中修改列表
def print_model(unprinted_designs,completed_models):
    """模拟打印每个设计，直到没有未打印
    打印每个设计后，挪到 completed——models 中
    """
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print(f"print design {current_design}")
        completed_models.append(current_design)

def show_commpleted_model(commpleted_models):
    """显示所有打印好的模型"""
    print("\nThe following models have been printed:")
    for completed_model in commpleted_models:
        print(completed_model)

unprinted_design = ["phone case","rebot pendant","dodecahedron"]
completed_models = []
print_model(unprinted_design,completed_models)
show_commpleted_model(completed_models)
print(unprinted_design)
print(completed_models)


## 禁止函数修改列表  参数传入列表副本 使用切片
unprinted_design = ["phone case","rebot pendant","dodecahedron"]
completed_models = []
print_model(unprinted_design[:],completed_models)
show_commpleted_model(completed_models)
print(unprinted_design)
print(completed_models)


# 传递任意数量的实参   比如函数不知道需要接受多少个值
def make_pizza(*toppings):   # *topping表示创建 topping 元组
    """打印顾客点的所有配料"""
    print(toppings)
    for topping in toppings:
        print(topping)

make_pizza("pepperoni")
make_pizza("mushrooms","green peppers","extra cheese")

## 结合位置实参和任意数量的实参
def make_pizza(size,*toppings):   # *topping表示创建 topping 元组
    """概述要制作的pizza"""
    print(f"\nMaking a {size}-inch pizza with the following toppings:")
    for topping in toppings:
        print(topping)
make_pizza(16,"pepperoni")
make_pizza(12,"mushrooms","green peppers","extra cheese")


## 使用任意数量的关键字实参
def build_profile(first,last,**user_info):
    """创建字典，包含所知道的用户的一切"""
    user_info["first_name"] = first
    user_info["last_name"] = last
    return user_info

user_profile = build_profile("albert","einstein",location = "priceton",field = "physics")
print(user_profile)


# 将函数存储在模块中 import 导入
## 导入整个模块
"""见 08_函数_import_example: pizza.py % making_pizzas.py"""

## 导入特定函数
"""见 08_函数_import_example: pizza.py % making_pizzas2.py"""

## 使用 as 给函数指定别名
"""见 08_函数_import_example: pizza.py % making_pizzas3.py"""

## 使用 as 给模块指定别名
"""见 08_函数_import_example: pizza.py % making_pizzas4.py"""

## 模块中所有函数
"""见 08_函数_import_example: pizza.py % making_pizzas5.py"""
"""非自己编写的大型模块最好不要用这种方式，如果当前项目和导入模块有相同名称的函数，可能会导致覆盖"""

